package org.example.filter;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.example.pojo.SysUser;
import org.example.util.JwtUtils;
import org.example.vo.HttpResult;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.annotation.Resource;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author：无敌暴龙战士
 * @Package：org.example.filter
 * @Project：learn_spring_security
 * @name：JwtFilter
 * @Date：2025/2/13 20:36
 * @Filename：JwtFilter
 * @Description:
 */
@Component
public class JwtFilter extends OncePerRequestFilter {
    @Resource
    ObjectMapper objectMapper;
    @Resource
    JwtUtils jwtUtils;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {

        String requestURI = request.getRequestURI();
        if (requestURI.equals("/login")) {
            doFilter(request, response, filterChain);
        }

        String strAuth = request.getHeader("Authorization");
        if (StringUtils.isEmpty(strAuth)) {
            HttpResult result = HttpResult.builder()
                    .code(0)
                    .msg("jwt is null")
                    .build();
            printFront(request, response, result);
        }
        String jwtToken = strAuth.replace("bearer", "");
        boolean b = jwtUtils.verifyToken(jwtToken);
        if (!b) {
            HttpResult result = HttpResult.builder()
                    .code(0)
                    .msg("jwt has problem")
                    .build();
            printFront(request, response, result);
        }
        String userInfo = jwtUtils.getUserInfoFromToken(jwtToken);
        List<String> userAuthList = jwtUtils.getUserAuthFromToken(jwtToken);
        //反序列化
        SysUser sysUser = objectMapper.readValue(userInfo, SysUser.class);
        List<SimpleGrantedAuthority> authorityList = userAuthList.stream().map(SimpleGrantedAuthority::new).collect(Collectors.toList());
        UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(sysUser, null, authorityList);

        SecurityContextHolder.getContext().setAuthentication(token);
        doFilter(request,response,filterChain);
    }

    private void printFront(HttpServletRequest request, HttpServletResponse response, HttpResult httpResult) throws IOException {
        String strResponse = objectMapper.writeValueAsString(httpResult);
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json;charset=utf-8");
        PrintWriter writer = response.getWriter();
        writer.println(strResponse);
        writer.flush();
    }
}
